package com.vision.core.cl.ui.component;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor.Ignore;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.dnd.core.client.DND.Feedback;
import com.sencha.gxt.dnd.core.client.DND.Operation;
import com.sencha.gxt.dnd.core.client.DndDropEvent;
import com.sencha.gxt.dnd.core.client.DndDropEvent.DndDropHandler;
import com.sencha.gxt.dnd.core.client.GridDragSource;
import com.sencha.gxt.dnd.core.client.GridDropTarget;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.AbstractHtmlLayoutContainer.HtmlData;
import com.sencha.gxt.widget.core.client.container.HorizontalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.HtmlLayoutContainer;
import com.sencha.gxt.widget.core.client.container.SimpleContainer;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.vision.core.cl.ui.TopFieldLabel;

/**
 * Contains two {@link Grid}s side by side. 
 * 
 * @author Mark
 *
 */
public abstract class DualGridPanel<T> extends SimpleContainer {
	
	interface Binder extends UiBinder<Widget, DualGridPanel<?>> {}
	
	private static final Binder binder = GWT.create(Binder.class);

	@UiField HorizontalLayoutContainer formContainer;
	
	@UiField TopFieldLabel leftGridLabel;
	@UiField(provided = true) Grid<T> leftGrid;
	
	@UiField TopFieldLabel rightGridLabel;
	@UiField(provided = true) Grid<T> rightGrid;
	
	@Ignore @UiField TextButton allRightBtn;
	@Ignore @UiField TextButton rightBtn;
	@Ignore @UiField TextButton allLeftBtn;
	@Ignore @UiField TextButton leftBtn;
	
	public DualGridPanel() {
		initializeLeftGrid();
		initializeRightGrid();
		
		Widget w = binder.createAndBindUi(this);
		setWidget(w);
	}
	
	protected void initializeLeftGrid() {
		leftGrid = createLeftGrid();
		
		// Provide drag and drop support
		new GridDragSource<T>(leftGrid);
		GridDropTarget<T> target = new GridDropTarget<T>(leftGrid);
		target.setFeedback(Feedback.APPEND);
		target.setOperation(Operation.MOVE);
		target.addDropHandler(new DndDropHandler() {
			@SuppressWarnings("unchecked")
			@Override
			public void onDrop(DndDropEvent event) {
				if (event.getData() instanceof List<?>) {
					List<T> list = (List<T>) event.getData();
					onRightToLeft(list);
				}
			}
		});
	}
	
	protected void initializeRightGrid() {
		rightGrid = createRightGrid();
		
		// Provide drag and drop support
		new GridDragSource<T>(rightGrid);
		GridDropTarget<T> target = new GridDropTarget<T>(rightGrid);
		target.setFeedback(Feedback.APPEND);
		target.setOperation(Operation.MOVE);
		target.addDropHandler(new DndDropHandler() {
			@SuppressWarnings("unchecked")
			@Override
			public void onDrop(DndDropEvent event) {
				if (event.getData() instanceof List<?>) {
					List<T> list = (List<T>) event.getData();
					onLeftToRight(list);
				}
			}
		});
	}
	
	public void setLeftGridLabel(String label) {
		leftGridLabel.setText(label);
	}
	
	public void setRightGridLabel(String label) {
		rightGridLabel.setText(label);
	}
	
	public Grid<T> getLeftGrid() {
		return leftGrid;
	}
	
	public Grid<T> getRightGrid() {
		return rightGrid;
	}
	
	public void clearBoth() {
		leftGrid.getStore().clear();
		rightGrid.getStore().clear();
	}
	
	// Abstract Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	protected abstract Grid<T> createLeftGrid();
	
	protected abstract Grid<T> createRightGrid();
	
	protected abstract void onLeftToRight(List<T> list);
	
	protected abstract void onRightToLeft(List<T> list);
	
	// UiFactory Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	@UiFactory
	HtmlLayoutContainer initializeFormContainer() {
		return new HtmlLayoutContainer(getLayout());
	}
	
	@UiFactory
	HtmlData createHtmlData() {
		return new HtmlData("");
	}
	
	// UiHandler Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Called when the '>>' button is clicked. Subclasses must override this
	 * method to perform processing.
	 * 
	 * @param e
	 */
	@UiHandler("allRightBtn")
	protected void allRightClicked(SelectEvent e) {
		
	}
	
	/**
	 * Called when the '>' button is clicked. Subclasses must override this
	 * method to perform processing.
	 * 
	 * @param e
	 */
	@UiHandler("rightBtn")
	protected void rightClicked(SelectEvent e) {
		
	}
	
	/**
	 * Called when the '<' button is clicked. Subclasses must override this
	 * method to perform processing.
	 * 
	 * @param e
	 */
	@UiHandler("leftBtn")
	protected void leftClicked(SelectEvent e) {
	}
	
	/**
	 * Called when the '<<' button is clicked. Subclasses must override this
	 * method to perform processing.
	 * 
	 * @param e
	 */
	@UiHandler("allLeftBtn")
	protected void allLeftClicked(SelectEvent e) {
		
	}
	
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	protected native String getLayout() /*-{
	    return [ 
	    '<table width=100% height=100% cellpadding=0 cellspacing=0>',
		    '<tr>',
			    '<td class=left width=48% height=100% valign=top></td>',
			    '<td class=middle width=10% align=center valign=top></td>',
			    '<td class=right width=48% valign=top></td>',
		    '</tr>',
	    '</table>'
		].join("");
	}-*/;
	
}
